package com.siashan.unipay4j.wx;

import com.siashan.unipay4j.biz.PayBiz;
import com.siashan.unipay4j.biz.PayBizProperties;
import com.siashan.unipay4j.biz.PayBizUtil;
import com.siashan.unipay4j.core.exception.Unipay4jException;
import com.siashan.unipay4j.core.pay.*;
import com.siashan.unipay4j.core.transfer.ITransfer;
import com.siashan.unipay4j.wx.complaint.WxPayComplaint;
import com.siashan.unipay4j.wx.conf.WxApp;
import com.siashan.unipay4j.wx.conf.WxConfigUtil;
import com.siashan.unipay4j.wx.conf.WxMchConfig;

import java.util.Map;

/**
 * 微信支付工程服务类
 *
 * @author siashan
 * @since v1.0.1
 **/
public class WxPayFactoryProvider {
    /**
     * 微信配置文件
     */
    private WxPayProperties wxPayProperties;

    private PayBizProperties payBizProperties;

    private Map<String, WxApp> appMap;
    private Map<String, PayBiz> bizMap;

    /**
     * 微信工厂类
     */
    private WxPayFactory wxPayFactory;

    public WxPayFactoryProvider(WxPayProperties wxPayProperties, WxPayFactory wxPayFactory, PayBizProperties payBizProperties) {
        this.wxPayProperties = wxPayProperties;
        this.wxPayFactory = wxPayFactory;
        this.payBizProperties = payBizProperties;
        this.appMap = WxConfigUtil.transAppMap(this.wxPayProperties.getConfig().getApps());
        this.bizMap = PayBizUtil.transBizMap(this.payBizProperties.getBizs());
    }

    /**
     * 获取支付对象
     *
     * @param appCode 应用code
     * @param bizCode 业务代码
     * @return 支付类
     */
    public IPayment getPayment(String appCode, String bizCode) {
        WxApp wxApp = getWxApp(appCode);
        return wxPayFactory.getPayment(wxApp.getTradeType(), initPayConfig(wxApp.getAppId(), PayBizUtil.getPayNotifyUrl(bizMap,bizCode)));
    }


    /**
     * 获取回调对象
     *
     * @return 回调类
     */
    public INotify getNotify() {
        return wxPayFactory.getNotify(initPayConfig());
    }


    /**
     * 获取查询对象
     *
     * @return 查询类
     */
    public IQuery getQuery(String appCode, String bizCode) {
        WxApp wxApp = getWxApp(appCode);
        return wxPayFactory.getQuery(initPayConfig(wxApp.getAppId(), PayBizUtil.getPayNotifyUrl(bizMap,bizCode)));
    }


    /**
     * 获取转账对象
     *
     * @return 转账类
     */
    public ITransfer getTransfer(String appCode) {
        WxApp wxApp = getWxApp(appCode);
        return wxPayFactory.getTransfer(initPayConfig(wxApp.getAppId()));
    }

    /**
     * 获取退款对象
     *
     * @return 退款类
     */
    public IRefund getRefund(String appCode, String bizCode) {
        WxApp wxApp = getWxApp(appCode);
        return wxPayFactory.getRefund(initPayConfig(wxApp.getAppId(), PayBizUtil.getRefundNotifyUrl(bizMap,bizCode)));
    }

    /**
     * 获取关单对象
     *
     * @return 关单类
     */
    public IClose getClose(String appCode, String bizCode) {
        WxApp wxApp = getWxApp(appCode);
        return wxPayFactory.getClose(initPayConfig(wxApp.getAppId(), PayBizUtil.getPayNotifyUrl(bizMap,bizCode)));
    }


    public WxPayComplaint getComplaint(){
        return  wxPayFactory.getComplaint(initPayConfig());
    }


    private WxPayConfig initPayConfig() {
        return initPayConfig(null, null);
    }

    private WxPayConfig initPayConfig(String appId) {
        return initPayConfig(appId, null);
    }

    private WxPayConfig initPayConfig(String appId, String notifyUrl) {
        WxPayConfig wxPayConfig = new WxPayConfig();
        // set mch config
        wxPayConfig.setMchId(this.wxPayProperties.getConfig()
                .getMchId());
        WxMchConfig mchConfig = this.wxPayProperties.getConfig().getMchConfig();
        wxPayConfig.setKey(mchConfig.getKey());
        wxPayConfig.setV3Key(mchConfig.getV3Key());
        wxPayConfig.setCertPath(mchConfig.getCertPath());
        wxPayConfig.setSignType(mchConfig.getSignType());
        wxPayConfig.setMerchantPrivateKeyPath(mchConfig.getMerchantPrivateKeyPath());
        wxPayConfig.setMerchantSerialNumber(mchConfig.getMerchantSerialNumber());
        wxPayConfig.setRsaPubKey(mchConfig.getRsaPubKey());
        wxPayConfig.setVersion(mchConfig.getVersion());
        // set appId
        wxPayConfig.setAppId(appId);
        // set notifyUrl
        wxPayConfig.setNotifyurl(notifyUrl);
        return wxPayConfig;
    }

    private WxApp getWxApp(String appCode) {
        WxApp wxApp = this.appMap.get(appCode);
        if (null == wxApp) {
            throw new Unipay4jException("无效的appCode，请检查应用配置");
        }
        return wxApp;
    }
}
